<?php

namespace App\Model\Article;

use EasySwoole\ORM\ {
    AbstractModel,
    Utility\Schema\Table,
};
use EasySwoole\Mysqli\QueryBuilder;
use EasySwoole\ORM\Collection\Collection;
use App\Model\Base;

/**
 * 文章分类
 * Class Nav
 */
class Nav extends Base
{

    protected $tableName = 'nav';

    /**
     * 表的字段
     * @return Table
     */
    public function schemaInfo(bool $isCache = true): Table
    {
        $table = new Table($this->tableName);
        $table->colSmallInt('id')->setIsPrimaryKey(true);
        $table->colVarChar('name', 20);
        $table->colVarChar('path', 255);
        $table->colSmallInt('parent_id');
        $table->colTinyInt('display');
        $table->colTinyInt('is_show');
        /* alter table nav add is_show tinyint(1) default 0 comment '0、不展示在首页 1、展示在首页',
        modify id smallint unsigned auto_increment, modify parent_id smallint unsigned comment '分类id', 
        modify display tinyint(1) default 0 comment '0、显示 1、不显示' ;
        */
        return $table;
    }

    /**
     * @description: 关联文章，首页
     * @param {*}
     * @return {*}
     */
    public function homeArticle()
    {
        return $this->hasMany(Article::class, function(QueryBuilder $query){
            $query->fields(['id', 'name', 'update_time', 'navs_id']);
            $query->where('display', 0);
            $query->orderBy('update_time', 'DESC');
            $query->limit('10');
            return $query;
        }, 'id', 'navs_id');
    }

    /**
     * @description: 关联父级分类
     * @param {*}
     * @return {*}
     */
    public function parentNav()
    {
        return $this->hasOne(Nav::class, function(QueryBuilder $query){
            $query->fields(['id', 'name']);
            return $query;
        }, 'parent_id', 'id');
    }

    /**
     * @description: 范围查询条件
     * @param {*}
     * @return {*}
     */
    public function scopWhere()
    {
        $this->where('display', 0);
        return $this;
    }

    /**
     * @description: 获取首页分类
     * @param {*}
     * @return {*}
     */
    public function getHomeNavs()
    {
        return static::tryCatch(function() {
            $where = [
                'parent_id' => 0,
                'is_show'   => 1,
            ];
            $data  = $this->scopWhere()->where($where)->field('id,name')
                    ->order('id', 'asc')->limit(10)->all();
            $result = $data->toArray();
            return $result;
        }, [], []);
    }

    /**
     * @description: 获取首页分类下文章
     * @param {*}
     * @return {*}
     */
    public function getHomeNavArts()
    {
        return static::tryCatch(function() {
            $where = [
                'parent_id' => 0,
                'is_show'   => 1,
            ];
            $data  = $this->with(['homeArticle'])->scopWhere()->where($where)->field('id,name')
                    ->order('id', 'asc')->limit(10)->all();
            $result = $data->toArray();
            foreach ($data as $key => $val) {
                $result[$key]['articles'] = (new Collection($val->homeArticle))->toArray();
            }
            return $result;
        }, [], []);
    }

    /**
     * @description: 获取分类及其子分类
     * @param int $nav_id 分类id
     * @return {*}
     */
    public function getNavAndChildren(int $nav_id)
    {
        return static::tryCatch(function($nav_id) {
            $where = ['id' => $nav_id];
            $nav = $this->where($where)->field('id,name,path,parent_id')->get();
            if (!$nav) {
                return [];
            }
            $childrens = $this->getNavChildrens($nav_id, $nav['path']);
            $childrens[] = ['id' => $nav['id'], 'name' => $nav['name']];
            return $childrens;
        }, [], $nav_id);
    }

    /**
     * @description: 获取指定分类的子分类
     * @param int $nav_id 分类id
     * @param string $path 分类路径
     * @return {*}
     */
    public function getNavChildrens(int $nav_id, ?string $path = null)
    {
        return static::tryCatch(function($nav_id, $path) {
            if (!$path) {
                $path = $this->scopWhere()->where('id', $nav_id)->val('path');
            }
            $where = ['path' => [$path . ':%', 'like']];
            return $this->scopWhere()->where($where)->field('id,name')->all()->toArray();
        }, [], $nav_id, $path);
    }

    /**
     * @description: 获取分类下级或同级
     * @param int nav_id 分类id
     * @return {*}
     */
    public function getNavOrChildren($nav_id)
    {
        return static::tryCatch(function($nav_id) {
            if ($nav_id != 0) {
                $nav = $this->scopWhere()->where('id', $nav_id)
                        ->field('id,name,path,parent_id')->get();
                if (!$nav) {
                    return [];
                }
                $datas = $this->getNavChildrens($nav_id, $nav['path']);

                if (!$datas) {
                    if ($nav['parent_id']) {
                        $where = ['parent_id' => $nav['parent_id']];
                    } else {
                        $where = ['parent_id' => 0];
                    }
                    $datas = $this->scopWhere()->where($where)->field('id,name')->all()->toArray();
                }
            } else {
                $where = ['parent_id' => 0];
                $datas = $this->scopWhere()->where($where)->field('id,name')->all()->toArray();
            }
            return $datas;
        }, [], $nav_id);
    }

    /**
     * @description: 分页列表连贯查询
     * @param {*}
     * @return {*}
     */    
    protected function adminPagesCoherent()
    {
        $this->with(['parentNav'])->field(['id', 'name', 'display', 'parent_id']);
        return $this;
    }

    /**
     * @description: 分页列表数据处理
     * @param {*}
     * @return {*}
     */    
    protected function adminPagesData($list)
    {
        $datas = $list->toArray();
        foreach ($list as $key => $val) {
            $datas[$key]['parentName'] = $val->parentNav ? $val->parentNav->name : '';
        }
        return $datas;
    }

   /**
     * @description: 拼接创建参数
     * @param {*}
     * @return {*}
     */
    protected function createDatas()
    {
        return [
            'name'      => $this->param['name'],
            'parent_id' => (int)$this->param['parent_id'],
            'display'   => (int)$this->param['display'],
            'is_show'   => (int)$this->param['is_show'],
        ];
    }

    /**
     * @description: 创建后处理
     * @param AbstractModel $model
     * @return {*}
     */
    protected function createAfter($model)
    {
        if ($this->param['path']) {
            $path  = $this->param['path'];
            $paths = explode(':', $path);
            if (end($paths) != $model->id) {
                $path = $this->param['path'] . ':' . $model->id;
            }
        } else {
            $path = $model->id;
        }
        $model->update(['path' => $path]);
    }

    /**
     * @description: 空数据
     * @param {*}
     * @return {*}
     */
    public function nullData()
    {
        return [
            'id'        => '',
            'name'      => '',
            'path'      => '',
            'parent_id' => '',
            'display'   => '',
            'is_show'   => '',
        ];
    }
}